﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Xml.Linq;

namespace MonoRailRSS.Models
{
    public abstract class Repository<T> : IRepository<T> where T : Entity
    {
        private readonly string xmlFile = string.Format("{0}.xml", typeof(T).Name);
        protected List<T> _items;

        public Repository()
        {
            if (File.Exists(xmlFile))
                _items = TryReadItemsFromFile(xmlFile);
            else
                _items = new List<T>();
        }

        public void Add(T item)
        {
            item.Id = FindAvailableId(_items);
            _items.Add(item);
            WriteItemsFile(xmlFile, _items);
        }

        public bool Exists(Predicate<T> predicate)
        {
            return Find(predicate) != null;
        }

        public T Find(Predicate<T> predicate)
        {
            return _items.Find(predicate);
        }

        public IEnumerable<T> GetAll()
        {
            return _items;
        }

        public void Update(T item)
        {
            WriteItemsFile(xmlFile, _items);
        }

        public void Delete(T item)
        {
            _items.Remove(item);
            WriteItemsFile(xmlFile, _items);
        }

        private int FindAvailableId(List<T> items)
        {
            items.Sort((x, y) => x.Id.CompareTo(y.Id));
            for (int i = 0; i < items.Count; i++)
                if (items[i].Id != i)
                    return i;
            return items.Count;
        }

        protected abstract List<T> TryReadItemsFromFile(string filename);
        protected abstract void WriteItemsFile(string filename, IEnumerable<T> items);
   }
}
